home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / prog / amisl090.zip / SWITCHAR.ASM < prev    next >
Assembly Source File  |  1992-09-12  |  9KB  |  314 lines

  1. ;-----------------------------------------------------------------------
  2. ; SWITCHAR.ASM  Public Domain 1992 Ralf Brown
  3. ;        You may do with this software whatever you want, but
  4. ;        common courtesy dictates that you not remove my name
  5. ;        from it.
  6. ;
  7. ; Provide the undocumented switch-character services which were removed
  8. ; from MSDOS 5.0.  The TSR is larger than necessary because it is
  9. ; illustrating the use of both private INT 2Dh functions and a private
  10. ; API entry point.
  11. ;
  12. ; Version 0.90
  13. ; LastEdit: 9/12/92
  14. ;-----------------------------------------------------------------------
  15.  
  16. __TINY__ equ 1                ; using Tiny model
  17.     INCLUDE AMIS.MAC
  18.  
  19.     @Startup 2,00                 ; need DOS 2.00
  20.                     ; this macro also takes care of declaring
  21.                     ; all the segments in the required order
  22.  
  23. ;-----------------------------------------------------------------------
  24. ;
  25. VERSION_NUM equ 005Ah    ; v0.90
  26. VERSION_STR equ "0.90"
  27.  
  28. ;-----------------------------------------------------------------------
  29. ;
  30. ; useful macros
  31. ;
  32. LODSB_ES MACRO
  33.     DB 26h,0ACh    ; LODSB ES:
  34.     ENDM
  35.  
  36. ;-----------------------------------------------------------------------
  37. ; Put the resident code into its own segment so that all the offsets are
  38. ; proper for the new location after copying it into a UMB or down into
  39. ; the PSP.
  40. ;
  41. TSRcode@
  42.  
  43. ;-----------------------------------------------------------------------
  44. ; Declare data storage for the TSR
  45. ;
  46.  
  47. switchar_active  db 1
  48. current_switchar db '/'
  49.  
  50. ;-----------------------------------------------------------------------
  51. ; Define the private API entry point handler
  52. ;
  53. switchar_API proc far
  54.     cmp    al,1
  55.     ja    switchar_API_done
  56.     xchg    byte ptr RESIDENT_CODE:switchar_active,al
  57. switchar_API_done:
  58.     ret
  59. switchar_API endp
  60.  
  61. ;-----------------------------------------------------------------------
  62. ; Define our private INT 2Dh function
  63. ;
  64. private:
  65.     cmp     al,10h            ; INT 2D/AH=mpx/AL=10h is set-state
  66.     jne    not_private_func
  67.     mov    al,bl            ; BL=new state
  68.     push    cs
  69.     call    near ptr switchar_API
  70.     mov    ah,al            ; return previous state
  71.     mov    al,0FFh            ; indicate success
  72.     iret
  73.  
  74. not_private_func:
  75.     mov    al,0            ; indicate not supported
  76.     iret
  77.  
  78. ;-----------------------------------------------------------------------
  79. ; Define our removal code
  80. ;    deactivate, then report that we don't have a resident uninstaller
  81. ;    but are now disabled
  82. ;
  83. remov:
  84.     mov    RESIDENT_CODE:switchar_active,0
  85.     mov    bx,0            ; seg of block to free (will be patched)
  86. ALTMPX$PSP equ word ptr ($-2)        ; magic name of word to be patched with
  87.                     ; actual memory block segment by TSR
  88.                     ; installation code
  89.     mov    al,4            ; no resident remover, now disabled
  90.     ret
  91.  
  92. ;-----------------------------------------------------------------------
  93. ; Declare the interrupt vectors hooked by the program, then set up the
  94. ; Alternate Multiplex Interrupt Spec handler
  95. ; Note: the resident remover must precede the ALTMPX if it defines ALTMPX$PSP
  96. ;    otherwise ALTMPX$PSP will be multiply-defined
  97. ;
  98.     HOOKED_INTS 21h            ; hooking INT 21h in add. to INT 2Dh
  99.     ALTMPX    'Ralf B','SWITCHAR',VERSION_NUM,'Switch-character support',private,switchar_API,,remov,Y
  100.  
  101. ;-----------------------------------------------------------------------
  102. ; Now the meat of the resident portion, the MSDOS interrupt handler.
  103. ; We can save one byte by specifying the hardware reset handler set up by
  104. ; the ALTMPX macro above
  105. ;
  106.     ISP_HEADER 21h,hw_reset_2Dh
  107.     cmp    ah,37h            ; switchar/availdev call?
  108.     jne    use_old_int21
  109.     cmp    switchar_active,0    ; is TSR enabled?
  110.     je    use_old_int21        ; if not, pass through
  111.     cmp    al,1            ; check if switchar call
  112.     ja    use_old_int21        ; if not, pass through
  113.     mov    al,0            ; always return 'success'
  114.     jb    get_switchar
  115. set_switchar:
  116.     mov    current_switchar,dl
  117.     iret
  118.  
  119. get_switchar:
  120.     mov    dl,current_switchar
  121.     iret
  122.  
  123. use_old_int21:
  124.     jmp    ORIG_INT21h
  125.  
  126. TSRcodeEnd@
  127.  
  128. ;-----------------------------------------------------------------------
  129.  
  130. _TEXT SEGMENT 'CODE'
  131.     ASSUME cs:_TEXT,ds:NOTHING,es:NOTHING,ss:NOTHING
  132.  
  133. banner    db 'SWITCHAR v',VERSION_STR,'  Public Domain 1992 Ralf Brown',13,10,'$'
  134. usage    db 'Usage:',9,'SWITCHAR i',9,'install',13,10
  135.     db 9,'SWITCHAR r',9,'remove from memory',13,10
  136.     db 9,'SWITCHAR d',9,"disable TSR but don't unload",13,10
  137.     db 9,'SWITCHAR e',9,'enable TSR',13,10
  138.     db 9,'SWITCHAR <x>',9,'set switch character to <x>',13,10
  139.     db '$'
  140. not_installed_msg db "Not " ;continues on next line
  141. installed_msg     db "Installed.",13,10,"$"
  142. cant_install_msg db "Unable to install.",13,10,"$"
  143. already_inst_msg db "Already installed.",13,10,"$"
  144. cant_remove_msg  db "Can't remove from memory.",13,10,"$"
  145. removed_msg     db "Removed.",13,10,"$"
  146. switchar_set_msg db "Switch character has been set.",13,10,"$"
  147. not_set_msg      db "Switch character has NOT been set.",13,10,"$"
  148. not_supported_msg db "Switch character not supported.",13,10,"$"
  149. enabled_msg     db "SWITCHAR enabled $"
  150. disabled_msg     db "SWITCHAR disabled $"
  151. was_on_msg     db "(was enabled).",13,10,"$"
  152. was_off_msg     db "(was disabled).",13,10,"$"
  153. cant_disable_msg db "Can't disable SWITCHAR.",13,10,"$"
  154.  
  155. entry_point dd ?
  156.  
  157.     @Startup2    Y
  158.     push    ds
  159.     pop    es
  160.     ASSUME    ES:_INIT
  161.     push    cs
  162.     pop    ds
  163.     ASSUME    DS:_TEXT
  164.     ;
  165.     ; say hello 
  166.     ;
  167.     DISPLAY_STRING banner
  168.     mov    bx,1000h        ; set memory block to 64K
  169.     mov    ah,4Ah            ; to have some memory to allocate
  170.     int    21h
  171.     mov    si,81h            ; SI -> commandline
  172.     cld
  173. cmdline_loop:
  174.     lodsb_es
  175.     cmp    al,' '            ; skip blanks and tabs on commandline
  176.     je    cmdline_loop
  177.     cmp    al,9
  178.     je    cmdline_loop
  179.     mov    ah,al            ; remember exact switch character
  180.     and    al,0DFh            ; force to uppercase
  181.     cmp    al,'R'
  182.     je    removing
  183.     cmp    al,'I'
  184.     je    installing
  185.     cmp    al,'E'
  186.     je    enabling
  187.     cmp    al,'D'
  188.     je    disabling
  189.         cmp     ah,' '
  190.     jbe    show_usage
  191.     jmp    set_switch_char
  192.  
  193. show_usage:
  194.     mov    dx,offset _TEXT:usage
  195.     jmp    exit_with_error
  196.  
  197. removing:
  198.     UNINSTALL cant_uninstall
  199.     mov    dx,offset _TEXT:removed_msg
  200. exit_with_message:
  201.     mov    ah,9
  202.     int    21h
  203.         mov     ax,4C00h
  204.     int    21h
  205.  
  206. enabling:
  207.     IF_INSTALLED enable_TSR
  208. not_installed:
  209.     mov    dx,offset _TEXT:not_installed
  210.     jmp    exit_with_error
  211.  
  212. disabling:
  213.     IF_INSTALLED disable_TSR
  214.     jmp    not_installed
  215.  
  216. installing:
  217.     INSTALL_TSR ,BEST,,inst_notify,already_installed,cant_install
  218.  
  219. cant_uninstall:
  220.         mov     dx,offset _TEXT:cant_remove_msg
  221.     jmp short exit_with_error
  222. already_installed:
  223.     mov    dx,offset _TEXT:already_inst_msg
  224. exit_with_error:
  225.     mov    ah,9
  226.     int    21h
  227.     mov    ax,4C01h
  228.     int    21h
  229.  
  230. set_switch_char:
  231.     mov    dl,ah
  232.     push    dx
  233.     mov    ax,3701h
  234.     int    21h
  235.     pop    cx            ; get back requested switch character
  236.     mov    dx,offset _TEXT:not_supported_msg
  237.     cmp    al,0            ; supported?
  238.     jne    set_switch_done        ; branch if not
  239.     mov    ax,3700h
  240.     int    21h            ; get current switch character
  241.     cmp    dl,cl            ; now same as request switch char?
  242.     mov    dx,offset _TEXT:switchar_set_msg
  243.     je    set_switch_done
  244.     mov    dx,offset _TEXT:not_set_msg
  245. set_switch_done:
  246.     jmp    exit_with_message
  247.  
  248. cant_install:
  249.     mov    dx,offset _TEXT:cant_install_msg
  250.     jmp    exit_with_error
  251.  
  252. inst_notify:
  253.     DISPLAY_STRING _TEXT:installed_msg
  254.     ret
  255.  
  256. ;-----------------------------------------------------------------------
  257. ; on entry, AH=multiplex number
  258. ;
  259. ; for this example program, the 'enable' call will be made via a private
  260. ; INT 2Dh function, while the 'disable' call will be made via the FAR
  261. ; CALL entry point.
  262. ;
  263.  
  264. enable_TSR proc
  265.     mov    al,10h            ; private func, "set state"
  266.     mov    bl,1            ; new state = enabled
  267.     int    2Dh            ; set state, returns AH=old state
  268.     mov    al,ah
  269.     mov    dx,offset _TEXT:enabled_msg
  270. display_state_and_exit:
  271.     push    ax            ; remember prior state
  272.     mov    ah,9            ; display string
  273.     int    21h
  274.     pop    ax            ; get back prior state
  275.     mov    dx,offset _TEXT:was_on_msg
  276.     cmp    al,0
  277.     jne    display_state
  278.     mov    dx,offset _TEXT:was_off_msg
  279. display_state:
  280.     jmp    exit_with_message
  281. enable_TSR endp
  282.  
  283. ;-----------------------------------------------------------------------
  284. ; on entry, AH=multiplex number
  285. ;
  286. ; for this example program, the 'enable' call will be made via a private
  287. ; INT 2Dh function, while the 'disable' call will be made via the FAR
  288. ; CALL entry point.
  289. ;
  290.  
  291. disable_TSR proc
  292.     mov    al,1            ; function "get API entry"
  293.     int    2Dh    
  294.     cmp    al,0FFh            ; supported?
  295.     jne    disable_not_supported
  296.     mov    word ptr _TEXT:entry_point+2,dx
  297.     mov    word ptr _TEXT:entry_point,bx
  298.     mov    al,0            ; function is disable
  299.     call    dword ptr _TEXT:entry_point
  300.     mov    dx,offset _TEXT:disabled_msg
  301.     jmp    display_state_and_exit
  302. disable_not_supported:
  303.     mov    dx,offset _TEXT:cant_disable_msg
  304.     jmp    exit_with_error
  305. disable_TSR endp
  306.  
  307. ;-----------------------------------------------------------------------
  308.  
  309. _TEXT ENDS
  310.  
  311.      end INIT
  312.  
  313.  
  314.